package com.immcque.paint.pen.page;

import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Pair;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.androidkun.xtablayout.XTabLayout;
import com.blankj.utilcode.util.FileUtils;
import com.immcque.paint.R;
import com.immcque.paint.ShaderNative;
import com.immcque.paint.pen.TexturePen;
import com.immcque.paint.pen.page.setting.BaseFragment;
import com.immcque.paint.pen.page.setting.EraserSettingFragment;
import com.immcque.paint.pen.page.setting.FillSettingFragment;
import com.immcque.paint.pen.page.setting.IBrushSetting;
import com.immcque.paint.pen.page.setting.PaintSettingFragment;
import com.immcque.paint.util.DialogUtils;
import com.immcque.paint.util.PhotosHelper;
import com.immcque.paint.util.StorageHelper;
import com.immcque.paint.widget.StopScrollViewPager;
import com.immcque.paint.widget.TouchView;
import com.immcque.paint.widget.WhiteboardTextureView;
import com.immcque.paint.widget.dialog.LoadingDialogFragment;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class PaintMainActivity extends AppCompatActivity {

    private ImageView ivBack;
    private ImageView ivUndo;
    private ImageView ivRedo;
    private ImageView ivSave;
    private WhiteboardTextureView whiteView;
    private TouchView touchView;
    private XTabLayout tabFuncMenu;
    private StopScrollViewPager vpContent;
    private BrushInfoConfig curPaintConfig = BrushManager.INSTANCE.getDefaultBrushInfoConfig();//画笔
    private BrushInfoConfig curEraserConfig = BrushManager.INSTANCE.getDefaultBrushInfoConfig();//橡皮
    private BrushInfoConfig curFillConfig = BrushManager.INSTANCE.getDefaultBrushInfoConfig();//橡皮
    private BrushInfoConfig curConfig = BrushManager.INSTANCE.getDefaultBrushInfoConfig();//当前绘制
    private boolean saveGallery=false;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.paint_activity_paint_main);
        initView();
        initData();
    }

    private void initData() {
        curPaintConfig.setOutType(TexturePen.DRAW);
        curEraserConfig.setOutType(TexturePen.ERASER);
        curFillConfig.setOutType(TexturePen.FILL);
        curFillConfig.setBrushWidth(2);
        curFillConfig.setRes(BrushManager.INSTANCE.getFillBrushRes());
        ArrayList<Pair<String,BaseFragment>> fragments = getFragments();
        MenuPagerAdapter menuPagerAdapter = new MenuPagerAdapter(getSupportFragmentManager(), fragments);
        vpContent.setAdapter(menuPagerAdapter);
        vpContent.setOffscreenPageLimit(fragments.size());
        vpContent.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                if (position == 0) {//画笔
                    whiteView.setTouchType(TouchView.TouchType.PEN);
                    nativeSetPaintStyle(curPaintConfig);
                    copyStyle(curConfig, curPaintConfig);
                } else if (position == 1) {//橡皮擦
                    whiteView.setTouchType(TouchView.TouchType.PEN);
                    nativeSetPaintStyle(curEraserConfig);
                    copyStyle(curConfig, curEraserConfig);
                }
                else if (position == 2) {//填充
                    whiteView.setTouchType(TouchView.TouchType.FILL);
                    nativeSetPaintStyle(curFillConfig);
                    copyStyle(curConfig, curFillConfig);
                }
                nativeSetPaintColor(curConfig.getCurrColorInt());
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        tabFuncMenu.setupWithViewPager(vpContent);
        whiteView.init(touchView, new WhiteboardTextureView.IWhiteboardStatus() {
            @Override
            public void hasPen(boolean undoDisable, boolean redoDisable) {

            }
        }, curConfig);
        ivRedo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                whiteView.redo();
            }
        });
        ivUndo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                whiteView.undo();
            }
        });
        ivBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                closeEdit();
            }
        });
        ivSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showSaveDialog();
            }
        });
    }

    private void closeEdit() {
        DialogUtils.INSTANCE.showTip(PaintMainActivity.this, getString(R.string.paint_model_is_cancel_draw),
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        finish();
                        dialogInterface.dismiss();
                    }
                });
    }



    private void showSaveDialog() {
        String cacheDir = StorageHelper.getExternalCacheDir(PaintMainActivity.this).getAbsolutePath() + File.separator + "file_cache" + File.separator + "paint_cache";
        FileUtils.createOrExistsDir(cacheDir);
        String path =(saveGallery?StorageHelper.getCameraPath(PaintMainActivity.this):
                cacheDir) +File.separator + System.currentTimeMillis()+".png";
        LoadingDialogFragment loadingDialogFragment = new LoadingDialogFragment();
        loadingDialogFragment.show(getSupportFragmentManager(),"LoadingDialogFragment");
        ShaderNative.glSave(path, new ShaderNative.ICallBack() {
            @Override
            public void voidCallBack() {
                loadingDialogFragment.dismissAllowingStateLoss();
                if (saveGallery) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            File file = new File(path);
                            PhotosHelper.refreshSystemPhoto(PaintMainActivity.this, file);
                            Toast.makeText(PaintMainActivity.this, R.string.paint_model_saved_to_album, Toast.LENGTH_SHORT).show();
                        }
                    });
                }
                Intent intent = new Intent();
                intent.putExtra("extra_result_cache_path",path);
                setResult(RESULT_OK,intent);
                finish();
            }
        });
    }

    private void copyStyle(BrushInfoConfig curConfig, BrushInfoConfig setConfig) {
        curConfig.setRes(setConfig.getRes());
        curConfig.setBrushWidth(setConfig.getBrushWidth());
        curConfig.setOutType(setConfig.getOutType());
        curConfig.setCurrColorInt(setConfig.getCurrColorInt());
    }

    private ArrayList<Pair<String,BaseFragment>> getFragments() {
        ArrayList<Pair<String,BaseFragment>> fragments = new ArrayList<>();
        //画笔
        PaintSettingFragment paintSettingFragment = PaintSettingFragment.getInstance(new IBrushSetting() {
            @Override
            public void selectBrush(BrushInfoConfig info) {
                nativeSetPaintStyle(info);
                curPaintConfig.setRes(info.getRes());
                curPaintConfig.setBrushWidth(info.getBrushWidth());
                curPaintConfig.setOutType(info.getOutType());
                copyStyle(curConfig, curPaintConfig);
            }

            @Override
            public void setColor(int colorInt) {
                nativeSetPaintColor(colorInt);
                curPaintConfig.setCurrColorInt(colorInt);
                copyStyle(curConfig, curPaintConfig);
            }
        });
        fragments.add(new Pair<>(getString(R.string.paint_model_paint),paintSettingFragment));
        //橡皮
        EraserSettingFragment eraserSettingFragment = EraserSettingFragment.getInstance(new IBrushSetting() {
            @Override
            public void selectBrush(BrushInfoConfig info) {
                nativeSetPaintStyle(info);
                curEraserConfig.setRes(info.getRes());
                curEraserConfig.setBrushWidth(info.getBrushWidth());
                curEraserConfig.setOutType(info.getOutType());
                copyStyle(curConfig, curEraserConfig);
            }

            @Override
            public void setColor(int colorInt) {
                nativeSetPaintColor(colorInt);
                curEraserConfig.setCurrColorInt(colorInt);
                copyStyle(curConfig, curEraserConfig);
            }
        });
        fragments.add(new Pair<>(getString(R.string.paint_model_eraser),eraserSettingFragment));
        //填充
        FillSettingFragment fillSettingFragment = FillSettingFragment.getInstance(new IBrushSetting() {
            @Override
            public void selectBrush(BrushInfoConfig info) {
                nativeSetPaintStyle(info);
                curFillConfig.setRes(info.getRes());
                curFillConfig.setBrushWidth(info.getBrushWidth());
                curFillConfig.setOutType(info.getOutType());
                copyStyle(curConfig, curFillConfig);
            }

            @Override
            public void setColor(int colorInt) {
                nativeSetPaintColor(colorInt);
                curFillConfig.setCurrColorInt(colorInt);
                copyStyle(curConfig, curFillConfig);
            }
        });
        fragments.add(new Pair<>(getString(R.string.paint_model_fill),fillSettingFragment));
        return fragments;
    }

    private void nativeSetPaintColor(int color) {
        float a = Color.alpha(color) * 1f / 255f;
        float r = Color.red(color) * 1f / 255f;
        float g = Color.green(color) * 1f / 255f;
        float b = Color.blue(color) * 1f / 255f;
        ShaderNative.glPaintColor(a, r, g, b);
    }

    private void nativeSetPaintStyle(BrushInfoConfig info) {
        boolean isRotate = info.getRes().isRotate();
        Bitmap brushBitmap = BrushManager.INSTANCE.getBrushBitmap(
                getResources(),
                BrushManager.INSTANCE.isAgainSetTexture(curConfig.getRes().getId(), info)
        );
        ShaderNative.glSetPaintTexture(
                brushBitmap,
                isRotate,
                info.getBrushWidth(),
                info.getOutType()
        );

    }

    private void initView() {
        ivBack = (ImageView) findViewById(R.id.iv_back);
        ivUndo = (ImageView) findViewById(R.id.iv_undo);
        ivRedo = (ImageView) findViewById(R.id.iv_redo);
        ivSave = (ImageView) findViewById(R.id.iv_save);
        whiteView = (WhiteboardTextureView) findViewById(R.id.white_view);
        touchView = (TouchView) findViewById(R.id.touch_view);
        tabFuncMenu = (XTabLayout) findViewById(R.id.tab_func_menu);
        vpContent = (StopScrollViewPager) findViewById(R.id.vp_content);
    }

    @Override
    public void onBackPressed() {
        closeEdit();
    }

    class MenuPagerAdapter extends FragmentStatePagerAdapter {

        ArrayList<Pair<String,BaseFragment>> dataList;

        public MenuPagerAdapter(FragmentManager fm, ArrayList<Pair<String,BaseFragment>> dataList) {
            super(fm);
            this.dataList = dataList;
        }

        @Override
        public int getCount() {
            return dataList.size();
        }

        @Override
        public Fragment getItem(int position) {
            return dataList.get(position).second;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return dataList.get(position).first;
        }
    }

}